﻿using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Text.Json.Serialization;
using LightCAD.MathLib;
namespace LightCAD.Core.Elements
{
    /// <summary>
    /// 直径标注
    /// </summary>
    public class DimDiametric : LcElement
    {
        [JsonInclude, JsonPropertyName("S")]
        [JsonConverter(typeof(Vector2dConverter))]
        public Vector2 Start;
        [JsonInclude, JsonPropertyName("E")]
        [JsonConverter(typeof(Vector2dConverter))]
        public Vector2 End;
        [JsonInclude, JsonPropertyName("c")]
        [JsonConverter(typeof(Vector2dConverter))]
        public Vector2 Center;

        public string Dimtext;

        public Vector2 P;
        public DimDiametric()
        {
            this.Type = BuiltinElementType.DimDiametric;
        }

        public DimDiametric(Vector2 start, Vector2 end,string dimtext, Vector2 center) : this()
        {
            this.Start = start;
            this.End = end;
            this.Dimtext = dimtext;
            this.Center = center;
        }

        public override LcElement Clone()
        {
            var clone = new DimDiametric();
            clone.Copy(this);
            return clone;
        }
        public  double distance(Vector2 p1, Vector2 p2)
        {
            
            double result = 0;
            result = Math.Sqrt((p1.X - p2.X) * (p1.X - p2.X) + (p1.Y - p2.Y) * (p1.Y - p2.Y));
            return result;

        }
        public void Set(string value="",Vector2 start = null, Vector2 end = null, bool fireChangedEvent = true)
        {
            //PropertySetter:Center,Radius            
            if (!fireChangedEvent)
            {
                if (start != null) this.Start = start;
                if (end != null) this.End = end;
            }
            else
            {
                bool chg_start = (start != null && start != this.Start);
                if (chg_start)
                {
                    OnPropertyChangedBefore(nameof(start), this.Start, start);
                    var oldValue = this.Start;
                    this.Start = start;
                    OnPropertyChangedAfter(nameof(start), oldValue, this.Start);
                }
                bool chg_end = (end != null && end != this.End);
                if (chg_end)
                {
                    OnPropertyChangedBefore(nameof(end), this.End, end);
                    var oldValue = this.End;
                    this.End = end;
                    OnPropertyChangedAfter(nameof(end), oldValue, this.End);
                }
                if (value == "Start") { }
                //this.Dimtext = distance(this.Start, this.End).ToString("0.00");
                else
                    this.Dimtext = distance(this.Start, this.End).ToString("0.00");
            }
        }

        public override void Copy(LcElement src)
        {
            var dim = ((DimDiametric)src);
            this.Start = dim.Start;
            this.End = dim.End;
            this.Dimtext=dim.Dimtext;
            this.Center = dim.Center;
        }
        [JsonIgnore]
        public double Angle
        {
            get
            {
                return (this.End - this.Start).Angle();
            }
        }
        [JsonIgnore]
        public double DeltaX
        {
            get
            {
                return this.End.X - this.Start.X;
            }
        }

        [JsonIgnore]
        public double DeltaY
        {
            get
            {
                return this.End.Y - this.Start.Y;
            }
        }

        public override Box2 GetBoundingBox()
        {
            return new Box2().SetFromPoints(this.Start, this.End);
        }
        public override Box2 GetBoundingBox(Matrix3 matrix)
        {
            return new Box2().SetFromPoints(matrix.MultiplyPoint(this.Start), matrix.MultiplyPoint(this.End));
        }

        public override bool IntersectWithBox(Polygon2d testPoly, List<RefChildElement> intersectChildren = null)
        {
            var thisBox = this.BoundingBox;
            if (!thisBox.IntersectsBox(testPoly.BoundingBox))
            {
                //如果元素盒子，与多边形盒子不相交，那就可能不相交
                return false;
            }
            return GeoUtils.IsPolygonIntersectLine(testPoly.Points, this.Start, this.End)
                || GeoUtils.IsPolygonContainsLine(testPoly.Points, this.Start, this.End);
        }

        public override bool IncludedByBox(Polygon2d testPoly, List<RefChildElement> includedChildren = null)
        {
            var thisBox = this.BoundingBox;
            if (!thisBox.IntersectsBox(testPoly.BoundingBox))
            {
                return false;
            }
            return GeoUtils.IsPolygonContainsLine(testPoly.Points, this.Start, this.End);
        }

    }
}
